package com.zzl.bonds.ticket.exception;


import com.zzl.general.common.exception.ParamaErrorException;
import com.zzl.general.common.utils.Result;
import com.zzl.general.common.utils.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
 * 全局异常处理
 *
 * @author gull
 * @date 2021-04-08 15:36:59
 */
@RestControllerAdvice("com.zzl.bonds.ticket.controller")
@Slf4j
public class GlobalExceptionHandler {


    /**
     * 忽略参数异常处理器
     *
     * @param e 忽略参数异常
     * @return Result
     */

    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Result parameterMissingExceptionHandler(MissingServletRequestParameterException e) {
        return Result.error(ResultCode.ERROR_PARAM.getCode(), "请求参数 " + e.getParameterName() + " 不能为空");
    }

    /**
     * 缺少请求体异常处理器
     *
     * @param e 缺少请求体异常
     * @return Result
     */

    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result parameterBodyMissingExceptionHandler(HttpMessageNotReadableException e) {
        log.error("参数体不能为空", e);
        return Result.error(ResultCode.ERROR_PARAM);
    }

    /**
     * 参数效验异常处理器
     *
     * @param e 参数验证异常
     * @return ResponseInfo
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result parameterExceptionHandler(MethodArgumentNotValidException e) {
// 获取异常信息
        BindingResult exceptions = e.getBindingResult();
// 判断异常中是否有错误信息，如果存在就使用异常中的消息，否则使用默认消息
        if (exceptions.hasErrors()) {
            List<ObjectError> errors = exceptions.getAllErrors();
            if (!errors.isEmpty()) {
// 这里列出了全部错误参数，按正常逻辑，只需要第一条错误即可
                FieldError fieldError = (FieldError) errors.get(0);
                return Result.error(ResultCode.ERROR_PARAM.getCode(), fieldError.getDefaultMessage());
            }
        }
        return Result.error(ResultCode.ERROR_PARAM);
    }

    /**
     * 自定义参数错误异常处理器
     *
     * @param e 自定义参数
     * @return ResponseInfo
     */

    @ExceptionHandler({ParamaErrorException.class})
    public Result paramExceptionHandler(ParamaErrorException e) {
// 判断异常中是否有错误信息，如果存在就使用异常中的消息，否则使用默认消息
        if (!StringUtils.isEmpty(e.getMessage())) {
            return Result.error(ResultCode.ERROR_PARAM.getCode(), e.getMessage());
        }
        return Result.error(ResultCode.ERROR_PARAM);
    }

    /**
     * 其他异常
     *
     * @param e
     * @return
     */

    @ExceptionHandler({Exception.class})
    public Result otherExceptionHandler(Exception e) {
        log.error("其他异常", e);
// 判断异常中是否有错误信息，如果存在就使用异常中的消息，否则使用默认消息
        if (!StringUtils.isEmpty(e.getMessage())) {
            return Result.error(ResultCode.UNKNOWN_ERROR.getCode(), e.getMessage());
        }
        return Result.error(ResultCode.UNKNOWN_ERROR);
    }
}